package com.svms.save.utils;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;

/**
 * 
 * <p>
 * Title: 工具类
 * </p>
 * <p>
 * Description:
 * </p>
 * 
 * @author xuyang
 * @date 2019年6月27日
 */
public class CommonUtils {
	/**
	 * <p>
	 * Title: 生成UUID
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @author xuyang
	 * @date 2019年6月27日
	 * @return
	 */
	public static String getUUID() {
		String uuid = UUID.randomUUID().toString().replaceAll("-", "");
		return uuid;
	}

	/**
	 * 将组织机构编号后面的‘00’全部去掉，当遇到一个不为00的字符时停止,每次向前去除两个
	 * 
	 * @param orgcode
	 * @return
	 */
	public static String toNewsOrgCode(String orgcode) {
		if (StringUtils.isNotBlank(orgcode)) {
			boolean temp = false;
			orgcode = orgcode.replace("\r", "");
			orgcode = orgcode.replace("\n", "");
			do {
				if (orgcode.length() > 2) {
					String newstr = orgcode.substring(orgcode.length() - 2);
					if ("00".equals(newstr)) {
						orgcode = orgcode.substring(0, orgcode.length() - 2);
					} else {
						temp = true;
					}
				} else {
					temp = true;
				}
			} while (!temp);
		}
		return orgcode;
	}

	/**
	 * 将短的单位编码补全
	 * 
	 * @param org
	 * @param rootCode
	 * @return
	 */
	public static String allOrgCode(String org, final String rootCode) {
		if (StringUtils.isNotBlank(rootCode) && StringUtils.isNotBlank(org)) {
			int olen = org.length();
			int rlen = rootCode.length();
			for (int i = olen; i < rlen; i++) {
				org += "0";
			}
		}
		return org;
	}

	/**
	 * 
	 * <p>
	 * Title: 字符串补0
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @author xuyang
	 * @date 2019年7月9日
	 * @param str 字符串
	 * @param l   总长度
	 * @return
	 */
	public static String pad(String str, int l) {
		int i = str.length();
		while (i++ < l)
			str = "0" + str;
		return str;
	}

	/**
	 * 获取查询单位比对代码
	 * 
	 * @param org      单位代码简写
	 * @param rootCode 单位代码全拼
	 * @return org__00000...
	 */
	public static String allSearchOrgCode(String org, final String rootCode) {
		if (StringUtils.isNotBlank(rootCode) && StringUtils.isNotBlank(org)) {
			org = org + "__";
			org = allOrgCode(org, rootCode);
		}
		return org;
	}

	/**
	 * 封装查询的机构代码
	 * 
	 * @param org
	 * @return
	 */
	public static String toSearchOrg(final String org) {
		if (StringUtils.isNotBlank(org)) {
			int len = org.length();
			String norg = toNewsOrgCode(org) + "__";
			int nl = norg.length();
			for (int i = nl; i < len; i++) {
				norg += "0";
			}
			return norg;
		}
		return org;
	}

	/**
	 * 组织机构验证
	 * 
	 * @param nowcode 当前用户
	 * @param dbOrg   要比的
	 * @return
	 */
	public static boolean comOrgCode(String nowcode, String dbOrg) {
		if (nowcode != null && !"".equals(nowcode) && dbOrg != null && !"".equals(dbOrg)) {
			String t = toNewsOrgCode(nowcode);
			if (dbOrg.length() >= t.length()) {
				if (t.equalsIgnoreCase(dbOrg.substring(0, t.length()))) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 多个组织机构验证
	 * 
	 * @param nowcode 当前单位代码
	 * @param dbOrg   要比的单位代码
	 * @param isAfter 是下属单位还是本单位
	 * @return
	 */
	public static boolean comOrgCodeDouble(String nowcode, String dbOrgs, boolean isAfter) {
		boolean flag = false;
		if (null != nowcode && !"".equals(nowcode) && null != dbOrgs && !"".equals(dbOrgs)) {
			String[] nowcodeArg = dbOrgs.split(",");
			for (String str : nowcodeArg) {
				if (isAfter) {
					flag = comOrgCode(str, nowcode);
				} else {
					flag = str.equals(nowcode);
				}
				if (flag) {
					break;
				}
			}
		}
		return flag;
	}

	/**
	 * 基本类型解析
	 */
	public static Object parsePrimitive(String parameterTypeName, Object value) {
		final String booleanTypeName = "boolean";
		if (booleanTypeName.equals(parameterTypeName)) {
			return Boolean.valueOf(value.toString());
		}
		final String intTypeName = "int";
		if (intTypeName.equals(parameterTypeName)) {
			return Integer.valueOf(value.toString());
		}
		final String charTypeName = "char";
		if (charTypeName.equals(parameterTypeName)) {
			return value.toString().charAt(0);
		}
		final String shortTypeName = "short";
		if (shortTypeName.equals(parameterTypeName)) {
			return Short.valueOf(value.toString());
		}
		final String longTypeName = "long";
		if (longTypeName.equals(parameterTypeName)) {
			return Long.valueOf(value.toString());
		}
		final String floatTypeName = "float";
		if (floatTypeName.equals(parameterTypeName)) {
			return Float.valueOf(value.toString());
		}
		final String doubleTypeName = "double";
		if (doubleTypeName.equals(parameterTypeName)) {
			return Double.valueOf(value.toString());
		}
		final String byteTypeName = "byte";
		if (byteTypeName.equals(parameterTypeName)) {
			return Byte.valueOf(value.toString());
		}
		return null;
	}

	public static final Set<Class> BasicDataTypes = new HashSet<>();
	{
		BasicDataTypes.add(Integer.class);
		BasicDataTypes.add(Long.class);
		BasicDataTypes.add(Short.class);
		BasicDataTypes.add(Float.class);
		BasicDataTypes.add(Double.class);
		BasicDataTypes.add(Boolean.class);
		BasicDataTypes.add(Byte.class);
		BasicDataTypes.add(Character.class);
		BasicDataTypes.add(String.class);
	}

	/**
	 * 判断是否为基本数据类型包装类
	 */
	public static boolean isBasicDataTypes(Class clazz) {
		return BasicDataTypes.contains(clazz);
	}

	/**
	 * 基本类型包装类解析
	 */
	public static Object parseBasicTypeWrapper(Class<?> parameterType, Object value) {
		if (Number.class.isAssignableFrom(parameterType)) {
			Number number = (Number) value;
			if (parameterType == Integer.class) {
				return number.intValue();
			} else if (parameterType == Short.class) {
				return number.shortValue();
			} else if (parameterType == Long.class) {
				return number.longValue();
			} else if (parameterType == Float.class) {
				return number.floatValue();
			} else if (parameterType == Double.class) {
				return number.doubleValue();
			} else if (parameterType == Byte.class) {
				return number.byteValue();
			}
		} else if (parameterType == Boolean.class) {
			return Boolean.parseBoolean(value.toString());
		} else if (parameterType == Character.class) {
			return value.toString().charAt(0);
		}
		return null;
	}


	/**
	 * 
	 * <p>
	 * Title: 判断是否为数字
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @author xuyang
	 * @date 2019年8月27日
	 * @param p
	 * @return
	 */
	public static boolean isNumber(String str) {
		// TODO Auto-generated method stub
		boolean b = false;
		try {
			Long.parseLong(str);
			b = true;
		} catch (NumberFormatException e) {
			b = false;
		}
		return b;
	}

	/**
	 * 
	 * <p>
	 * Title: 数组字符串拼接
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @author xuyang
	 * @date 2019年9月3日
	 * @param s 中间要拼接的字符
	 * @return
	 */
	public static String joinArr(String[] arr, String s) {
		// TODO Auto-generated method stub
		String res = "";
		if (null != arr && arr.length > 0) {
			for (int i = 0; i < arr.length; i++) {
				if (i == 0) {
					res += arr[i];
				} else {
					res += s + arr[i];
				}
			}
		}
		return res;
	}
	
	/**
	 * 
	 * <p>
	 * Title: 数组字符串拼接
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @author xuyang
	 * @date 2019年9月3日
	 * @param s 中间要拼接的字符
	 * @return
	 */
	public static String joinArr(List<String> arr, String s) {
		// TODO Auto-generated method stub
		String res = "";
		if (null != arr && arr.size() > 0) {
			for (int i = 0; i < arr.size(); i++) {
				if (i == 0) {
					res += arr.get(i);
				} else {
					res += s + arr.get(i);
				}
			}
		}
		return res;
	}
	/**
	 * 
	 * <p>Title: 获取请求客户端真实IP地址，可穿透多层代理</p>  
	 * <p>Description: </p>
	 * @author xuyang
	 * @date 2019年9月5日
	 * @param request
	 * @return
	 */
	public static String getClientIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_CLUSTER_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_FORWARDED");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_VIA");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("REMOTE_ADDR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}
	/**
	 * 
	 * <p>Title: 获取客户端请求的第一个IP地址</p>  
	 * <p>Description: </p>
	 * @author xuyang
	 * @date 2019年9月5日
	 * @param request
	 * @return
	 */
	public static String getClientIpAddrFirst(HttpServletRequest request) {
		String ip = getClientIpAddr(request);
		if(null != ip && ip.indexOf(",") >= 0) {
			ip = ip.split(",")[0];
		}
		return ip;
	}
	
	/**
	 * 
	 * <p>Title: 将JSON对象转换成MAP,LIST</p>  
	 * <p>Description: </p>
	 * @author xuyang
	 * @date 2019年6月26日
	 * @param obj	要转换的对象
	 * @return
	 */
	public static Object convertToMapList(Object obj) {
		if(null != obj) {
			if(obj.getClass() == JSONObject.class) {
				JSONObject jsonObj = (JSONObject) obj;
				Map<String, Object> result = JSONObject.parseObject(jsonObj.toJSONString(), new TypeReference<Map<String, Object>>(){});
				if(null != result && !result.isEmpty()) {
					Iterator<String> keys = result.keySet().iterator();
					while(keys.hasNext()) {
						String key = keys.next();
						Object val = result.get(key);
						Object cVal = convertToMapList(val);
						if(val.getClass() != cVal.getClass()) {
							result.put(key, cVal);
						}
					}
				}
				return result;
			}else if(obj.getClass() == JSONArray.class) {
				JSONArray jsonArr = (JSONArray) obj;
				List<Object> result = JSONObject.parseArray(jsonArr.toJSONString(), Object.class);
				if(null != result && !result.isEmpty()) {
					for(int i=0;i<result.size();i++) {
						Object val = result.get(i);
						Object cVal = convertToMapList(val);
						if(val.getClass() != cVal.getClass()) {
							result.set(i, cVal);
						}
					}
				}
				return result;
			}
		}
		return obj;
	}
}
